package com.sdhs.system.service.impl;

import com.sdhs.system.domain.GcContract;
import com.sdhs.system.domain.GcContractMiddle;
import com.sdhs.system.domain.GcContractParty;
import com.sdhs.system.mapper.GcContractMapper;
import com.sdhs.system.mapper.GcContractMiddleMapper;
import com.sdhs.system.mapper.GcContractPartyMapper;
import com.sdhs.system.service.IGcContractService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


/**
 * 合同主表Service业务层处理
 *
 * @author add
 * @date 2025-04-04
 */
@Service
public class GcContractServiceImpl implements IGcContractService
{
    @Autowired
    private GcContractMapper gcContractMapper;

    @Autowired
    private GcContractMiddleMapper gcContractMiddleMapper;

    @Autowired
    private GcContractPartyMapper gcContractPartyMapper;
    /**
     * 查询合同主表
     *
     * @param id 合同主表主键
     * @return 合同主表
     */
    @Override
    public GcContract selectGcContractById(Long id)
    {
        return gcContractMapper.selectGcContractById(id);
    }
    /**
     * 查询合同主表
     *
     * @param contractId 合同主表合同id
     * @return 合同主表
     */
    @Override
    public GcContract selectGcContractByContractId(String contractId)
    {
        return gcContractMapper.selectGcContractByContractId(contractId);
    }

    /**
     * 查询合同主表列表
     *
     * @param gcContract 合同主表
     * @return 合同主表
     */
    @Override
    public List<GcContract> selectGcContractList(GcContract gcContract) {
         List<String> expenseTypes = gcContract.getExpenseTypes();
        if (expenseTypes != null && expenseTypes.contains("收入类")) {
            gcContract.setIncomeExpenseType("支出类");
        }
        // 1. 查询所有主合同
        List<GcContract> mainContracts = gcContractMapper.selectGcContractsList(gcContract);


        // 2. 收集所有主合同的编号（用于批量查询子合同）
        List<String> mainContractNums = mainContracts.stream()
                .map(GcContract::getNum)
                .collect(Collectors.toList());

        if(!mainContractNums.isEmpty()){
            // 3. 批量查询所有子合同（IsSupplementaryContract = "1" 且 OriginalContractNum 在 mainContractNums 中）
            GcContract queryParam = new GcContract();
            queryParam.setIsSupplementaryContract("1");
            queryParam.setOriginalContractNums(mainContractNums); // 假设 Mapper 支持批量查询

            List<GcContract> supplementaryContracts = gcContractMapper.selectGcContractList(queryParam);

            // 4. 按 OriginalContractNum 分组（Key=主合同Num，Value=对应的子合同列表）
            Map<String, List<GcContract>> supplementaryMap = supplementaryContracts.stream()
                    .collect(Collectors.groupingBy(GcContract::getOriginalContractNum));

            // 5. 将子合同挂载到主合同的 Children 属性
            for (GcContract mainContract : mainContracts) {
                mainContract.setChildren(new ArrayList<>());
                if(mainContract.getNum().equals(mainContract.getOriginalContractNum())){
                    continue;
                }
                List<GcContract> children = supplementaryMap.getOrDefault(mainContract.getNum(), Collections.emptyList());
                if(children != null){
                    mainContract.setChildren(children);
                }
            }
        }

        return mainContracts;
    }

    /**
     * 新增合同主表
     *
     * @param gcContract 合同主表
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertGcContract(GcContract gcContract)
    {
        if (gcContract == null) {
            throw new IllegalArgumentException("合同为空");
        }

        // 如果有变更金额，则更新合同金额
        Optional.ofNullable(gcContract.getChangeMoney())
                .ifPresent(gcContract::setMoney);

        // 如果有变更金额（不含税），则更新合同金额（含税）
        Optional.ofNullable(gcContract.getNotChangeMoney())
                .ifPresent(gcContract::setNotMoney);
        // 如果是解除合同（"2" 表示解除合同），则修改名称
        if ("2".equals(gcContract.getIsSupplementaryContract())) {
            gcContract.setName(gcContract.getName() + "（已解除）");
        }

        int result = gcContractMapper.insertGcContract(gcContract);
        handler(gcContract);
        return result;
    }

    /**
     * 修改合同主表
     *
     * @param gcContract 合同主表 合同id修改
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateGcContract(GcContract gcContract)
    {
        // 如果有变更金额，则更新合同金额
        Optional.ofNullable(gcContract.getChangeMoney())
                .ifPresent(gcContract::setMoney);
        // 如果有变更金额（不含税），则更新合同金额（含税）
        Optional.ofNullable(gcContract.getNotChangeMoney())
                .ifPresent(gcContract::setNotMoney);
        // 如果是解除合同（"2" 表示解除合同），则修改名称
        if ("2".equals(gcContract.getIsSupplementaryContract())) {
            gcContract.setName(gcContract.getName() + "（已解除）");
        }
        int result = gcContractMapper.updateGcContract(gcContract);
        handler(gcContract);
        return result;
    }

    /**
     * 批量删除合同主表
     *
     * @param ids 需要删除的合同主表主键
     * @return 结果
     */
    @Override
    public int deleteGcContractByIds(Long[] ids)
    {
        return gcContractMapper.deleteGcContractByIds(ids);
    }

    /**
     * 删除合同主表信息
     *
     * @param id 合同主表主键
     * @return 结果
     */
    @Override
    public int deleteGcContractById(Long id)
    {
        return gcContractMapper.deleteGcContractById(id);
    }

    /**处理关联数据*/
    public void handler(GcContract gcContract) {
        List<GcContractMiddle> existingMiddles = gcContractMiddleMapper.selectGcContractMiddleByCode(gcContract.getContractId());

        // 先删除所有旧数据（放在循环外部）
        if (!existingMiddles.isEmpty()) {
            gcContractMiddleMapper.deleteGcContractMiddleById(gcContract.getContractId());
        }

        // 批量处理参与者数据
        List<GcContractParty> participants = gcContract.getParticipants();
        for (GcContractParty participant : participants) {
            // 处理中间表数据
            GcContractMiddle gcContractMiddle = new GcContractMiddle();
            gcContractMiddle.setContractId(gcContract.getContractId());
            gcContractMiddle.setPartyId(participant.getParticipantsCode());
            gcContractMiddleMapper.insertGcContractMiddle(gcContractMiddle);

            // 处理相对方表数据
            GcContractParty existingParty = gcContractPartyMapper.selectGcContractPartyByCode(participant.getParticipantsCode());
            if (existingParty == null) {
                gcContractPartyMapper.insertGcContractParty(participant);
            }
        }
    }
}
